package com.yonyou.crm.sprc.opportunity.service;

import com.yonyou.crm.base.doc.service.BaseDocBizServiceImpl;
import com.yonyou.crm.base.doc.service.BaseDocDetailBizServiceImpl;
import com.yonyou.crm.bpub.list.entity.AppListSpecialVO;
import com.yonyou.crm.bpub.list.entity.AppListVO;
import com.yonyou.crm.bpub.list.entity.AppListValueVO;
import com.yonyou.crm.bpub.refervalue.entity.ReferDataVO;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.EnumFieldRelation;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.field.relation.RefFieldRelation;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.common.rest.constant.AppCodeConstant;
import com.yonyou.crm.common.search.entity.AppSearchPlanEnum;
import com.yonyou.crm.cum.customer.service.CustomerBizServiceImpl;
import com.yonyou.crm.sact.schedule.entity.ScheduleObjectVO;
import com.yonyou.crm.sact.schedule.entity.ScheduleTaskcardVO;
import com.yonyou.crm.sact.schedule.service.ScheduleObjectBizServiceImpl;
import com.yonyou.crm.sact.schedule.service.ScheduleTaskcardBizServiceImpl;
import com.yonyou.crm.sprc.opportunity.entity.*;
import com.yonyou.crm.sprc.oppstage.service.OppstageBizServiceImpl;
import com.yonyou.crm.sys.modules.entity.MtObjTypeEnum;
import com.yonyou.crm.sys.modules.service.BiztypeBizServiceImpl;
import com.yonyou.crm.sys.org.service.SysOrgBizServiceImpl;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.crm.sys.user.service.UserBizServiceImpl;
import com.yonyou.iuap.context.InvocationInfoProxy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OpportunityBizServiceImpl extends BaseBizServiceImpl<OpportunityVO> {


    @Autowired
    private SysOrgBizServiceImpl orgService;
    @Autowired
    private EnumBizServiceImpl enumService;
    @Autowired
    OpportunityBBizServiceImpl bService;
    @Autowired
    UserBizServiceImpl userService;
    @Autowired
    CustomerBizServiceImpl customerService;
    @Autowired
    OppstageBizServiceImpl stageService;
    @Autowired
    BiztypeBizServiceImpl bizTypeService;
    @Autowired
    ScheduleObjectBizServiceImpl scheduleObjectService;
    @Autowired
    private ScheduleTaskcardBizServiceImpl stService;
    @Autowired
    private BiztypeBizServiceImpl biztypeService;
    @Autowired
    private BaseDocBizServiceImpl docService;
    @Autowired
	private BaseDocDetailBizServiceImpl baseDocDetailBizService;




    public Page<OpportunityVO> getList(Page<OpportunityVO> page, Map<String, Object> paramMap) {
        Page<OpportunityVO> opportunityPage = null;
        if (paramMap != null) {
        	//全部、我负责、我参与、我关注、已逾期
    		if ((paramMap.containsKey("option")) && (paramMap.get("option") != null)) {
    			int option = (int)paramMap.get("option");
    			String optionSql = "";
    			if (option == AppSearchPlanEnum.OWNER.getValue()) {
    				optionSql = " and opportunity.owner_user_id = "+InvocationInfoProxy.getParameter(LoginContextConstant.UserId);
    			} else if (option == AppSearchPlanEnum.REL.getValue()) {
    				optionSql = " and opportunity.id in (select product_id from sprc_opportunity_relusers where user_id = "+InvocationInfoProxy.getParameter(LoginContextConstant.UserId)+")";
    			} else if (option == AppSearchPlanEnum.FOLLOW.getValue()) {
    				optionSql = " and opportunity.id in (select product_id from sprc_opportunity_follow where user_id = "+InvocationInfoProxy.getParameter(LoginContextConstant.UserId)+")";
    			} else if (option == AppSearchPlanEnum.OVERDUE.getValue()) {
    				//TODO逾期 跟进中并已过预计签单时间，状态：跟进中枚举值未定
    				optionSql = " and (opportunity.state = 1 and opportunity.expect_sign_time < now())";
    			} else {
    				//TODO全部
    				optionSql = "";
    			}
    			paramMap.put("option", optionSql);
    		}
            opportunityPage = super.pageSelect(OpportunityVO.class, page, paramMap.keySet().toArray(new String[0]), paramMap.values().toArray(new Object[0]));
        } else {
            opportunityPage = super.pageSelect(OpportunityVO.class, page, null, null);
        }

        transOpportunity(opportunityPage.getData());
        getStageStayTime(opportunityPage.getData());
        return opportunityPage;
    }

    private List<OpportunityVO> getStageStayTime(List<OpportunityVO> list){
        if (list != null && list.size() > 0) {
            for(int i=0;i<list.size();i++){
                Date start = list.get(i).getStageStartTime();
                Date now = new Date();
                if(start==null){
                    String stageStayTime = "0小时";
                    list.get(i).setStageStayTime(stageStayTime);
                    continue;
                }
                long l=now.getTime()-start.getTime();
                long day=l/(24*60*60*1000);
                long hour=(l/(60*60*1000)-day*24);
                String stageStayTime = day +"天"+hour+"小时";
                list.get(i).setStageStayTime(stageStayTime);
            }
        }
        return  list;
        }

    private List<OpportunityVO> transOpportunity(List<OpportunityVO> opportunityList) {

        if (opportunityList != null && opportunityList.size() > 0) {

            List<FieldRelation<OpportunityVO>> relations = new ArrayList<FieldRelation<OpportunityVO>>();
            //参照项：组织
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "orgId", new String[]{"orgName"}, orgService, "selectFieldsByIds"));
            //参照项：部门
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "deptId", new String[]{"deptName"}, orgService, "selectFieldsByIds"));
            //参照项：客户
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "customerId", new String[]{"customerName"}, customerService, "selectFieldsByIds"));
            //参照项：负责员工
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "ownerUserId", new String[]{"ownerUserName"}, userService, "selectFieldsByIds"));
            //参照项：业务子类型
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "type", new String[]{"typeName"}, bizTypeService, "selectFieldsByIds"));

            //枚举项：商机状态
            relations.add(new EnumFieldRelation<OpportunityVO>(OpportunityVO.class, "state", "stateName", enumService, "opportunity_state"));
            //枚举项：商机阶段
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "saleStage", new String[]{"saleStageName"}, stageService, "selectFieldsByIds"));

            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "saleStage", new String[]{"saleStageName"}, enumService, "saleStage"));
            //枚举项：商机来源
            relations.add(new RefFieldRelation<OpportunityVO>(OpportunityVO.class, "source", new String[]{"sourceName"}, baseDocDetailBizService, "source"));

            new FieldRelationHandler<OpportunityVO>().handler(opportunityList, relations);
        }

        return opportunityList;
    }

    public OpportunityVO getDetail(Long id) {
    	Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("ownerId", new Long(InvocationInfoProxy.getParameter("id")));
		paramMap.put("id", id);
		
    	OpportunityVO newOpportunity = (OpportunityVO) dao.selectOne(OpportunityVO.class, "getOpportunityById", paramMap);
        //OpportunityVO newOpportunity = super.getVOById(OpportunityVO.class, id);
    	
    	if (newOpportunity != null) {
	        transOpportunity(Arrays.asList(newOpportunity));
	
	        List<OpportunityBVO> childList = bService.getVOSByOpportunityID(id);
	        //newOpportunity.setChildPage(bvoPage);
	        newOpportunity.setChildList(childList);
	        
	        Map<String, Object> param = new HashMap<String, Object>();
	        param.put("tenantId", Long.parseLong(InvocationInfoProxy.getTenantid()));
	        param.put("orgId", Long.parseLong(InvocationInfoProxy.getParameter(LoginContextConstant.OrgId)));
	        param.put("opportunityId", id);
	        List<Map<String, Object>> relUserListMap = dao.selectList(OpportunityVO.class, "selectRelUsers", param);
	        
	        List<UserVO> relUserList = new ArrayList<UserVO>();
	        for (Map<String, Object> map:relUserListMap) {
	        	UserVO user = new UserVO();
	        	user.setId(Long.parseLong(map.get("id").toString()));
	        	user.setName((String)map.get("name"));
	        	relUserList.add(user);
	        }
	        newOpportunity.setRelUserList(relUserList);
            Date start = newOpportunity.getStageStartTime();
            Date now = new Date();
            if(start==null){
                String stageStayTime = "0小时";
                newOpportunity.setStageStayTime(stageStayTime);
            }else{
                long l=now.getTime()-start.getTime();
                long day=l/(24*60*60*1000);
                long hour=(l/(60*60*1000)-day*24);
                String stageStayTime = day +"天"+hour+"小时";
                newOpportunity.setStageStayTime(stageStayTime);
            }
    	}
        return newOpportunity;
    }

    @Override
    protected void beforeSaveVO(OpportunityVO vo) {

        super.beforeSaveVO(vo);

        Long loginUserID = new Long(InvocationInfoProxy.getParameter("id"));
        Date date = new Date();

        vo.setTenantId(new Long(InvocationInfoProxy.getTenantid()));
        vo.setSysCreatedTime(date);
        vo.setSysCreatedUserId(loginUserID);
        vo.setSysModifiedTime(date);
        vo.setSysModifiedUserId(loginUserID);
        if (vo.getOwnerUserId() == null) {
        	vo.setOwnerUserId(loginUserID);
        }

    }

    public OpportunityVO insert(OpportunityVO opportunity) {
//        transOpportunity(Arrays.asList(opportunity));
        //先保存表头信息
        opportunity.setStageStartTime(new Date());
        OpportunityVO opportunityVO = super.saveVO(opportunity);
        Long id = opportunityVO.getId();
        List<OpportunityBVO> opportunityBVOS = opportunity.getChildList();
        if(opportunityBVOS != null && opportunityBVOS.size() > 0) {
            for (OpportunityBVO bvo : opportunityBVOS) {
                bvo.setOpportunityId(id);
            }
            //批量保存商机明细表体信息
            bService.batchInsert(opportunityBVOS);
        }
        return opportunityVO;
    }
    
    public OpportunityVO insert(OpportunityVO opportunity, Map<String, Object> param) {
        OpportunityVO opportunityVO = insert(opportunity);
        Map<String, String> relateMap = (Map<String, String>)param.get("relateMap");
        if ((relateMap != null) && (relateMap.size() > 0)) {
        	//TODO写入日程关联表
        	ScheduleObjectVO scheduleObject = new ScheduleObjectVO();
        	scheduleObject.setScheduleId(Long.valueOf( relateMap.get("id")));
        	Integer scheduleType = ScheduleObjectBizServiceImpl.getScheduleType(relateMap.get("type"));
        	scheduleObject.setScheduleType(scheduleType);
        	Long objType = ScheduleObjectBizServiceImpl.getObjType("opportunity");
        	scheduleObject.setObjType(objType);
        	scheduleObject.setObjId(opportunityVO.getId());
        	// 设置业务子类型
        	long subBnsType = ScheduleObjectBizServiceImpl.getBizObjType(String.valueOf(param.get("subBnsType")));
        	scheduleObject.setObjBiztype(subBnsType);
        	scheduleObjectService.save(scheduleObject);
        	//TODO 修改日程和任务卡关联表
        	ScheduleTaskcardVO scheduleTaskcard = new ScheduleTaskcardVO();
        	scheduleTaskcard.setScheduleId(Long.valueOf( relateMap.get("id")));
        	scheduleTaskcard.setScheduleType(scheduleType);
        	scheduleTaskcard.setObjType(objType);
        	scheduleTaskcard.setObjBiztype(subBnsType);
        	scheduleTaskcard.setWritten(1);
        	stService.update(scheduleTaskcard);
        }
        return opportunityVO;
    }

    @Override
    protected void beforeUpdateVO(OpportunityVO vo) {

        super.beforeUpdateVO(vo);

        vo.setSysModifiedTime(new Date());
        vo.setSysModifiedUserId(new Long(InvocationInfoProxy.getParameter("id")));
    }


    public OpportunityVO update(OpportunityVO opportunity) {
        transOpportunity(Arrays.asList(opportunity));
        //先修改表头信息
        OpportunityVO opportunityVO = super.updateVO(opportunity);
        executeChildUpdate(opportunityVO);
        return opportunityVO;
    }

    protected void executeChildUpdate(OpportunityVO opportunity) {
        List<OpportunityBVO> opportunityBVOS = opportunity.getChildList();
        if(opportunityBVOS==null||opportunityBVOS.size()==0){
            return;
        }
        List<OpportunityBVO> addList = new ArrayList<OpportunityBVO>();
        List<OpportunityBVO> updateList = new ArrayList<OpportunityBVO>();
        List<OpportunityBVO> deleteList = new ArrayList<OpportunityBVO>();
        for (OpportunityBVO bvo : opportunityBVOS) {
            String editState = bvo.getEditState();
            if ("add".equals(editState)) {
                bvo.setOpportunityId(opportunity.getId());
                addList.add(bvo);
            } else if ("update".equals(editState)) {
                updateList.add(bvo);
            } else if ("delete".equals(editState)) {
                deleteList.add(bvo);
            }
        }

        if (addList.size() > 0) bService.batchInsert(addList);

        if (updateList.size() > 0) bService.batchUpdate(updateList);

        if (deleteList.size() > 0) {
            List<Long> deleteIdList = new ArrayList<Long>();
            for (OpportunityBVO bvo : deleteList) {
                deleteIdList.add(bvo.getId());
            }
            bService.batchDeleteByIDs(OpportunityBVO.class, deleteIdList.toArray());
        }
    }

    protected String[] beforeBatchDeleteByIDS(String[] idArray) {
        //子表有数据 不让删除主表（刘日靖 描述：相关对象有数据 也不让删除  这点还需确认， 负责员工也是相关对象）
        //1.子表有数据不允许删除商机主表
        String[] ids = hasOneChild(idArray);
        return ids;
    }

    private String[] hasOneChild(String[] idArray) {
        List<String> successIdList = new ArrayList<>();
        for ( String id : idArray) {
            int childCount = bService.getChildCounntByOpportunityID(new Long(id));
            if(childCount == 0) {
                successIdList.add(id);
            }
        }
        return successIdList.toArray(new String[0]);
    }

    public String batchDelete(String[] idArray) {
        String[] ids = beforeBatchDeleteByIDS(idArray);
        int successNum = ids.length;
        int failNum = idArray.length - successNum;
        if(ids.length == 0) {
            throw new CrmBusinessException("成功"+successNum+"条，失败"+failNum+"条！");
        }
        super.batchDeleteByIDs(OpportunityVO.class, ids);
        String message = "成功"+successNum+"条，失败"+failNum+"条！";
        //throw new CrmBusinessException(PCCodeConstant.Success,message);
        return message;
    }
	
	public int delete(Long id){
		OpportunityVO vo = new OpportunityVO();
		vo.setId(id);
		this.beforeDeleteVO(vo);
		
		return dao.delete(vo);
	}
	
	//获取商机参照
	public List<ReferDataVO> getRefervalues(Page<OpportunityVO> page, Map<String, Object> paraMap) {
		// TODO 加权限
		Page<OpportunityVO> pageVO = dao.pageSelect(OpportunityVO.class, page, "selectRefervalues", "countRefervalues", paraMap);
		List<OpportunityVO> voList = pageVO.getData();
		
		List<ReferDataVO> rsList = new ArrayList<ReferDataVO>();
		for (OpportunityVO vo : voList) {
			ReferDataVO referDataVO = new ReferDataVO();
			referDataVO.setId(vo.getId().toString());
			referDataVO.setValue(vo.getName());
			
			rsList.add(referDataVO);
		}
		return rsList;
	}
	
	//获取商机参照
	public List<OpportunityVO> getRefervaluesForApp(Page<OpportunityVO> page, Map<String, Object> paraMap) {
		// TODO 加权限
		Page<OpportunityVO> pageVO = dao.pageSelect(OpportunityVO.class, page, "selectRefervalues", "countRefervalues", paraMap);
		List<OpportunityVO> voList = pageVO.getData();
		return voList;
	}

    public List getFunnel(Map<String, Object> searchMap) {
        List<Map<String, Object>> funnelData = dao.selectList(OpportunityVO.class, "selectFunnelData", searchMap);
        return  funnelData;
    }

    public Map<String,Object> getFilterConditon() {
        Map<String,Object> returnMap = new HashMap<>();

        Long tenant_id = new Long(InvocationInfoProxy.getTenantid());
        //1.获取商机类型的参照
        Map<String, Object> opporBiztypes = biztypeService.getModuleBiztypesForCurrentRole(new Long(MtObjTypeEnum.OPPORTUNITY.getValue() + ""));
        List<Map<String, Object>> biztypeList = (List<Map<String, Object>>)opporBiztypes.get("biztypeList");
        if(biztypeList != null && biztypeList.size() > 0) {
            for(Map<String,Object> map : biztypeList) {
                Object key = map.get("key");
                Object title = map.get("title");
                //2.遍历商机类型根据商机类型--找到对应的流程--获取该流程对应的商机阶段有哪些
                Map<String,Object> param = new HashMap<>();
                param.put("biztype",key);
                param.put("tenant_id",tenant_id);
                List<Map<String, Object>>  stageList = dao.selectList(OpportunityVO.class, "getStageByBiztype", param);
                if(stageList != null && stageList.size() > 0) {
                    map.put("stageList", stageList);
                }
            }
        }

        //3.商机来源：自定义档案中获取
        List<Map<String, Object>> oppSourceList = docService.getDocDetailListByDocname("商机来源");

        returnMap.put("biztypeList",biztypeList);
        returnMap.put("oppSourceList", oppSourceList);
        return  returnMap;
    }
    
    public Map<String, Object> getStageInfoByOpportunityId(Long id){
    	Map<String, Object> paramMap = new HashMap<>();
    	paramMap.put("id", id);
    	List<Map<String, Object>> list =  dao.selectList(OpportunityVO.class, "selectStageInfoByOpportunityId", paramMap);
    	Map<String, Object> res = new HashMap<>();
    	if (list != null) {
    		res = list.get(0);
    	}
    	return res;
    }
    
    
    public List<AppOpportunityStageVO> getStageListForOpportunity(Long id){
    	List<AppOpportunityStageVO> res = new ArrayList<>();
    	Map<String, Object> paramMap = new HashMap<>();
    	paramMap.put("id", id);
    	Map<String, Object> opp = getStageInfoByOpportunityId(id);
    	paramMap.put("oppStage", opp.get("stage_id"));
    	paramMap.put("sort", opp.get("sort"));
    	List<Map<String, Object>> list = dao.selectList(OpportunityVO.class, "selectStageForOpportunity", paramMap);
    	
    	if (list != null) {
    		for(Map<String, Object> item : list) {
    			Integer stageSort = Integer.valueOf(String.valueOf(item.get("oppStageSort")));
    			Integer stageIndex = stageSort - 1;
    			AppOpportunityStageVO stage = (res.size() >= stageSort) ? res.get(stageIndex) : null;
    			if (stage == null) {
	    			String stageId = String.valueOf(item.get("oppStageId"));
	    			String stageName = String.valueOf(item.get("oppStageName"));
	    			String isCurrent = String.valueOf(item.get("isCurrent"));
	    			String isComplete = String.valueOf(item.get("isComplete"));
	    			stage = new AppOpportunityStageVO(stageId, stageName, isCurrent, isComplete);
	    			res.add(stage);
    			}
    			
    			List<AppOpportunityDimensionVO> dimensionList = (stage.getDimensionlist() != null) ? stage.getDimensionlist() : new ArrayList<AppOpportunityDimensionVO>();
    			
    			//TODO 维度排序
    			Integer dimensionSort = Integer.valueOf(String.valueOf(item.get("oppDimensionSort")));
    			Integer dimensionIndex = dimensionSort - 1;
    			AppOpportunityDimensionVO dimension = (dimensionList != null && dimensionList.size() >= dimensionSort) ? dimensionList.get(dimensionIndex) : null;
    			//TODO 维度分值
    			String dimensionScore = "10";
    			if (dimension == null) {
    				String dimensionId = String.valueOf(item.get("oppDimensionId"));
    				String dimensionName = String.valueOf(item.get("oppDimensionName"));
    				dimension = new AppOpportunityDimensionVO(dimensionId, dimensionName, dimensionScore);
    				dimensionList.add(dimension);
    				stage.setDimensionlist(dimensionList);
    			}
    			
    			List<AppOpportunityActionVO> actionList = (dimension.getActionlist() != null) ? dimension.getActionlist() : new ArrayList<AppOpportunityActionVO>();
    			
    			//TODO 动作排序
    			Integer actionSort = Integer.valueOf(String.valueOf(item.get("oppActionSort")));
    			Integer actionIndex = actionSort - 1;
    			AppOpportunityActionVO action = (actionList != null && actionList.size() >= actionSort) ? actionList.get(actionIndex) : null;
    			if (action == null) {
    				String actionId = String.valueOf(item.get("oppActionId"));
    				String actionName = String.valueOf(item.get("oppActionName"));
    				String isSelect = String.valueOf(item.get("isFinish"));
    				String isExpected = String.valueOf(item.get("isSuggest"));
    				String score = "0";
    				if (item.containsKey("oppActionScore")) {
    					score = String.valueOf(item.get("oppActionScore"));
    				}
    				action = new AppOpportunityActionVO(actionId, actionName, isSelect, isExpected, score);
    				actionList.add(action);
    				dimension.setActionlist(actionList);
    			}
    		}
    	}
    	
    	return res;
    }
    
	public int saveStage(Map<String, Object> param){
		return dao.updateSql(OpportunityVO.class, "saveStage", param);
		
	}
	
	public List<AppOpportunityStageVO> stageInfo(Map<String, Object> param) {
		saveStage(param);
		return getStageListForOpportunity(Long.valueOf(String.valueOf(param.get("id"))));
	}
    
    public int saveAction(Map<String, Object> param){
    	return dao.updateSql(OpportunityVO.class, "saveAction", param);
    }
    
    
    /**
	 * 关注
	 * @param id
	 * @return
	 */
	public int saveFollow(Long id) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("tenantId", InvocationInfoProxy.getTenantid());
		param.put("opportunityId", id);
		param.put("userId", InvocationInfoProxy.getParameter("id"));
		int count = dao.countAll(OpportunityVO.class, "countFollow", param);
		if (count > 0) {
			return 1;
		}
		return dao.saveSql(OpportunityVO.class, "insertFollow", param);
	}
	
	/**
	 * 删除关注
	 * @param id
	 * @return
	 */
	public int deleteFollow(Long id) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("tenantId", InvocationInfoProxy.getTenantid());
		param.put("opportunityId", id);
		param.put("userId", InvocationInfoProxy.getParameter("id"));
		return dao.deleteSql(OpportunityVO.class, "deleteFollow", param);
	}

    public List<Map<String,Object>> getStageBybiztype(Long type) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("biztype", type);
        List<Map<String, Object>> stageList = dao.selectList(OpportunityVO.class, "getOppStageBybiztype", paramMap);
        return stageList;
    }

    public List<Map<String,Object>> getActionBybiztype(Long type) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("biztype", type);
        List<Map<String, Object>> actionList = dao.selectList(OpportunityVO.class, "getOppActionBybiztype", paramMap);
        return actionList;
    }

    public void insertMiddleTable(OpportunityVO newOpportunity, List<Map<String, Object>> stageList, List<Map<String, Object>> actionList) {


        if (stageList.size() > 0) {
            for (Map<String, Object> map : stageList) {
                map.put("opportunity_id", newOpportunity.getId());
                map.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
            }
            dao.saveSql(OpportunityVO.class, "batchInsertOppstage", stageList);
        }

        if (actionList.size() > 0) {
            for (Map<String, Object> map : actionList) {
                map.put("opportunity_id", newOpportunity.getId());
                map.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
            }
            dao.saveSql(OpportunityVO.class, "batchInsertOppresult", actionList);
        }

    }

    public List<Map<String,Object>> getResultById(Long id) {
        List<Map<String, Object>> resultList = dao.selectList(OpportunityVO.class, "getOppresultById", id);
        return resultList;
    }
    public List<Map<String,Object>> getStageById(Long id) {
        List<Map<String, Object>> stageList = dao.selectList(OpportunityVO.class, "getOppstageById", id);
        return stageList;
    }
    
    /**
	 * 商机赢单
	 * @param paramMap
	 * @return
	 */
	public void win(Map<String, Object> paramMap) {
		dao.updateSql(OpportunityVO.class, "opportunityWin", paramMap);
	}
	
	/**
	 * 商机输单
	 * @param paramMap
	 * @return
	 */
	public void lose(Map<String, Object> paramMap) {
		dao.updateSql(OpportunityVO.class, "opportunityLose", paramMap);
	}

    public int finishAction(Map<String,Object> paramMap) {
        return dao.updateSql(OpportunityVO.class, "finishAction", paramMap);
    }

    public int setCurrentStage(Map<String,Object> paramMap) {
        return dao.updateSql(OpportunityVO.class, "setCurrentStage", paramMap);
    }

    public Map<String,Object> getFunnelMoney(Map<String, Object> searchMap) {
        List<Map<String, Object>> funnelMoney = dao.selectList(OpportunityVO.class, "selectFunnelMoney", searchMap);
        Map<String,Object> map = new HashMap<String,Object>();
        if(funnelMoney!=null&&funnelMoney.size()>0){
            for(int i=0;i<funnelMoney.size();i++){
                if(funnelMoney.get(i).get("state").toString().equals("1")){
                    map.put("win",funnelMoney.get(i).get("money"));
                }
                if(funnelMoney.get(i).get("state").toString().equals("2")){
                    map.put("fail",funnelMoney.get(i).get("money"));
                }
                if(funnelMoney.get(i).get("state").toString().equals("3")){
                    map.put("goon",funnelMoney.get(i).get("money"));
                }
            }
        }
        return map;
    }

    public Map<String,Object> getOppForCusRelate(Long customerId, Integer limit) {
	    Map<String, Object> param = new HashMap<>();
	    param.put("customerId", customerId);
        param.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
        List<OpportunityVO> oppVOListForNum = dao.selectVoList(OpportunityVO.class, "getOppForCusRelate", param);
        param.put("limit", limit);
        List<OpportunityVO> oppVOList = dao.selectVoList(OpportunityVO.class, "getOppForCusRelate", param);
        transOpportunity(oppVOList);

        List<AppListVO> detaillist = new ArrayList<AppListVO>();
        Map<String,Object> opprelateMap = new HashMap<>();
        if (oppVOList != null && oppVOList.size() > 0) {
            for (int i = 0; i<oppVOList.size(); i++) {
                OpportunityVO opp = oppVOList.get(i);
                AppListVO listVO = tranVoToAppListVO(opp);
                detaillist.add(listVO);
            }

            opprelateMap.put("type","opportunity");     //相关对象类型，如：contact
            opprelateMap.put("name","商机");             //相关对象名称，如：联系人
            opprelateMap.put("num",oppVOListForNum == null ? 0 : oppVOListForNum.size());   //相关对象数量
            opprelateMap.put("isnew","Y");
            opprelateMap.put("detaillist",detaillist);
        }//是否支持新增（Y支持,N不支持）
        //具体相关对象的行数据显示（参考获取列表接口实现，具体见下方描述

        return  opprelateMap;
    }

    /**
     * 列表左右两侧图标
     * @param opp
     * @param specialList
     */
    private void getAppListSpecialVO(OpportunityVO opp, List<AppListSpecialVO> specialList) {
        AppListSpecialVO icon;

        icon = new AppListSpecialVO();
        icon.setType("percent");
        icon.setPosition("left");
        icon.setValue(opp.getWinProbability());
        specialList.add(icon);
    }

    /**
     * 将数据转化为App列表数据
     * @param opp
     * @return
     */
    public AppListVO tranVoToAppListVO(OpportunityVO opp) {
        AppListVO listVO = new AppListVO();
        listVO.setId(opp.getId());

        //左右两侧图标
        List<AppListSpecialVO> specialList = new ArrayList<>();
        getAppListSpecialVO(opp, specialList);
        listVO.setSpeciallist(specialList);

        List<List<AppListValueVO>> valueList = new ArrayList<>();
        List<AppListValueVO> colList = new ArrayList<>();
        AppListValueVO listValue;

        listValue = new AppListValueVO();
        listValue.setItemkey("name");
        listValue.setDisplayvalue(opp.getName());
        colList.add(listValue);

        valueList.add(colList);
        colList = new ArrayList<>();

        listValue = new AppListValueVO();
        listValue.setItemkey("stage");
        listValue.setDisplayvalue((opp.getSaleStageName() == null) ? "" : opp.getSaleStageName());
        colList.add(listValue);

        listValue = new AppListValueVO();
        listValue.setItemkey("stagestaytime");
        //根据阶段开始时间计算阶段停留时间
        Date stageStartTime = opp.getStageStartTime();
        String stagestaytime = getDataRangeStr(stageStartTime);
        listValue.setDisplayvalue(stagestaytime);
        colList.add(listValue);

        valueList.add(colList);
        colList = new ArrayList<>();

        listValue = new AppListValueVO();
        listValue.setItemkey("predicttime");
        String displayValue = opp.getExpectSignTime() == null ? "" : formateDate(opp.getExpectSignTime(), "yyyy-MM-dd");
        listValue.setDisplayvalue(displayValue);
        colList.add(listValue);

        listValue = new AppListValueVO();
        listValue.setItemkey("price");
        listValue.setDisplayvalue("¥"+((opp.getExpectSignMoney() == null) ? "" : opp.getExpectSignMoney()));
        colList.add(listValue);

        valueList.add(colList);
        colList = new ArrayList<>();

        listValue = new AppListValueVO();
        listValue.setItemkey("department");
        listValue.setDisplayvalue((opp.getDeptName() == null) ? "" : opp.getDeptName());
        colList.add(listValue);

        listValue = new AppListValueVO();
        listValue.setItemkey("ownerUser");
        listValue.setDisplayvalue((opp.getOwnerUserName() == null) ? "" : opp.getOwnerUserName());
        colList.add(listValue);

        valueList.add(colList);

        listVO.setValuelist(valueList);
        return listVO;
    }

    /**
     * 根据阶段开始时间计算阶段停留时间
     * @param stageStartTime
     * @return
     */
    private String getDataRangeStr(Date stageStartTime) {
        Date now = new Date();
        String stagestaytime = "0天0小时";
        if (stageStartTime != null) {
            long timeRange = now.getTime() - stageStartTime.getTime();
            if (timeRange != 0) {
                long days = timeRange/(1000 * 60 * 60 * 24);
                long hours = (timeRange-days*(1000 * 60 * 60 * 24))/(1000* 60 * 60);
                if (days == 0 && hours == 0) {
                    stagestaytime = "0天1小时";
                } else {
                    stagestaytime = days + "天" + hours + "小时";
                }
            }
        }
        return stagestaytime;
    }

    /**
     * 格式化日期类型数据
     * @param date
     * @param dateFormate
     * @return
     * @throws CrmMessageException
     */
    public String formateDate(Date date, String dateFormate){
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormate);
        return sdf.format(date);
    }

    /**
     * 变更商机负责人
     * @param param
     */
    public void changeOwner(OpportunityVO opportunityVO) {
        dao.updateSql(OpportunityVO.class, "changeOwner", opportunityVO);
    }
}
